package com.molichuxing.gateway.bff.financial.services.impl;

import com.molichuxing.framework.dto.Paged;
import com.molichuxing.framework.exception.BizException;
import com.molichuxing.gateway.bff.financial.convertor.Convert;
import com.molichuxing.gateway.bff.financial.entity.request.create.InvoiceCreateVo;
import com.molichuxing.gateway.bff.financial.entity.response.InvoiceVo;
import com.molichuxing.gateway.bff.financial.services.InvoiceBffService;
import com.molichuxing.services.business.dto.request.create.InvoiceBizCreateDto;
import com.molichuxing.services.business.service.InvoiceBizService;
import com.molichuxing.services.infrastructure.dto.request.modify.InvoiceDto;
import com.molichuxing.services.infrastructure.dto.response.SubcompanyDto;
import com.molichuxing.services.infrastructure.service.InvoiceService;
import com.molichuxing.services.infrastructure.service.SubcompanyService;
import com.molichuxing.services.property.InvoiceStatusEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 发票相关bff
 *
 * @author zhaopenghui
 * @date 2019年9月25日
 */
@Service("invoiceBffService")
public class InvoiceBffServiceImpl implements InvoiceBffService {
    private static final Logger logger = LoggerFactory.getLogger(InvoiceBffServiceImpl.class);

    @Resource
    private InvoiceService invoiceService;

    @Resource
    private InvoiceBizService invoiceBizService;

    @Resource
    private SubcompanyService subcompanyService;


    /**
     * 发票列表
     *
     * @param map key：userId Integer 用户id
     *            key：status Integer 状态
     * @return
     * @throws Exception
     */
    @Override
    public List<InvoiceVo> getInvoicePage(Map<String, Object> map) throws Exception {
        Integer pageNum = 1;
        Integer pageSize = 999999;
        Paged<InvoiceDto> invoicePage = invoiceService.getInvoicePage(map, pageNum, pageSize);
        if (null == invoicePage) {
            return new ArrayList<InvoiceVo>();
        }

        List<InvoiceDto> invoiceDtoList = invoicePage.getList();
        if (null == invoiceDtoList) {
            return new ArrayList<InvoiceVo>();
        }
        return Convert.toInvoiceVoList(invoiceDtoList);
    }

    /**
     * 发票添加
     *
     * @param invoiceCreateVo
     * @return
     * @throws Exception
     */
    @Override
    public Boolean createInvoiceApply(InvoiceCreateVo invoiceCreateVo, Integer userId) throws Exception {
        List<Integer> invoiceIdList = invoiceCreateVo.getInvoiceIdList();
        if (null == invoiceIdList || invoiceIdList.size() < 1) {
            return false;
        }

        Map<Integer, InvoiceDto> invoiceMap = invoiceService.getInvoiceMap(invoiceIdList);
        if (null == invoiceMap || invoiceMap.size() < 1 || invoiceMap.size() != invoiceIdList.size()) {
            return false;
        }

        createInvoiceApplyCheck(invoiceMap);
        Map<Integer, SubcompanyDto> subcompanyMap = getSubcompanyMap(invoiceMap);
        List<InvoiceBizCreateDto> invoiceBizCreateList = getInvoiceBizCreateList(invoiceCreateVo, invoiceMap, userId, subcompanyMap);
        Boolean invoiceBoolean = invoiceBizService.createInvoice(invoiceBizCreateList);
        if (!invoiceBoolean) {
            return false;
        }

        return invoiceService.modifyStatusById(invoiceIdList, InvoiceStatusEnum.HAVE_APPLY.getValue());
    }

    /**
     * 校验
     *
     * @param invoiceMap
     * @throws Exception
     */
    private void createInvoiceApplyCheck(Map<Integer, InvoiceDto> invoiceMap) throws Exception {
        LocalDateTime now = LocalDateTime.now();
        for (Map.Entry<Integer, InvoiceDto> m : invoiceMap.entrySet()) {
            InvoiceDto invoiceDto = m.getValue();
            if (null == invoiceDto) {
                continue;
            }

            Integer status = invoiceDto.getStatus();
            if (InvoiceStatusEnum.HAVE_APPLY.getValue() == status) {
                throw new BizException("存在已申请数据！请重新选择");
            } else if (InvoiceStatusEnum.HAVE_EXPIRED.getValue() == status) {
                throw new BizException("存在已过期数据！请重新选择");
            }

            LocalDateTime validityStartTime = invoiceDto.getValidityStartTime();
            LocalDateTime validityEndTime = invoiceDto.getValidityEndTime();
            if (now.isBefore(validityStartTime) && now.isAfter(validityEndTime)) {
                throw new BizException("未在开票有效期内！请重新选择");
            }
        }
    }

    /**
     * list集合
     *
     * @param invoiceCreateVo
     * @param invoiceMap
     * @param userId
     * @param subcompanyMap
     * @return
     */
    private List<InvoiceBizCreateDto> getInvoiceBizCreateList(InvoiceCreateVo invoiceCreateVo, Map<Integer, InvoiceDto> invoiceMap,
                                                              Integer userId, Map<Integer, SubcompanyDto> subcompanyMap) {
        List<Integer> invoiceIdList = invoiceCreateVo.getInvoiceIdList();
        List<InvoiceBizCreateDto> invoiceBizCreateList = new ArrayList<>();
        for (Integer invoiceId : invoiceIdList) {
            if (null == invoiceId) {
                continue;
            }

            InvoiceBizCreateDto invoiceBizCreateDto = new InvoiceBizCreateDto();
            invoiceBizCreateDto.setInvoiceId(invoiceId);
            invoiceBizCreateDto.setUserId(userId);
            BeanUtils.copyProperties(invoiceCreateVo, invoiceBizCreateDto);

            if (null == subcompanyMap || subcompanyMap.size() < 1) {
                continue;
            }
            InvoiceDto invoiceDto = invoiceMap.get(invoiceId);
            Integer subcompanyId = invoiceDto.getSubcompanyId();
            if (null == subcompanyId) {
                continue;
            }
            SubcompanyDto subcompanyDto = subcompanyMap.get(subcompanyId);
            if (null == subcompanyDto) {
                continue;
            }
            invoiceBizCreateDto.setSellName(subcompanyDto.getFullName());
            invoiceBizCreateDto.setSellTaxNumber(subcompanyDto.getTaxpayerIdNo());
            invoiceBizCreateDto.setSellAddress(subcompanyDto.getAddress());
            invoiceBizCreateDto.setSellPhone(subcompanyDto.getResponsibleAccountPhone());
            invoiceBizCreateDto.setSellBank(subcompanyDto.getAccountBank());
            invoiceBizCreateDto.setSellBankNumber(subcompanyDto.getBankNumber());
            invoiceBizCreateList.add(invoiceBizCreateDto);
        }
        return invoiceBizCreateList;
    }

    /**
     * 分子公司
     *
     * @param invoiceMap
     * @return
     * @throws Exception
     */
    private Map<Integer, SubcompanyDto> getSubcompanyMap(Map<Integer, InvoiceDto> invoiceMap) throws Exception {
        List<Integer> subcompanyIdList = new ArrayList<>();
        for (Map.Entry<Integer, InvoiceDto> m : invoiceMap.entrySet()) {
            InvoiceDto invoiceDto = m.getValue();
            if (null == invoiceDto) {
                continue;
            }
            Integer subcompanyId = invoiceDto.getSubcompanyId();
            subcompanyIdList.add(subcompanyId);
        }

        return subcompanyService.getSubcompanyNameByIds(subcompanyIdList);
    }

}
